/*
 * Copyright (c) 2009 Roman Savelyev
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "WaitE32ImageSize.h"
#include "HostLink.h"
#include "AppHookModel.h"
#include "Sandbox.h"
#include "Log.h"

static const TUint32 KExpectedHostSignalOne =   0xd0e32ba1;
static const TUint32 KExpectedHostSignalTwo =   0x71bafd84;
static const TUint32 KExpectedHostSignalThree = 0xcaedde09;

CWaitE32ImageSize* CWaitE32ImageSize::NewL(CAppHookModel& aModel)
    {
    LOG(_L("-->CWaitE32ImageSize::NewL"));
    CWaitE32ImageSize* self = new(ELeave) CWaitE32ImageSize(aModel);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    LOG(_L("<--CWaitE32ImageSize::NewL"));
    return self;
    }

CWaitE32ImageSize::CWaitE32ImageSize(CAppHookModel& aModel) : CActive(CActive::EPriorityStandard),
    iModel(aModel)
    {
    CActiveScheduler::Add(this);
    }

void CWaitE32ImageSize::ConstructL()
    {
    LOG(_L("-->CWaitE32ImageSize::ConstructL"));
    iState = EWaitForSignalOne;
    RequestHostData(iBuffer);
    LOG(_L("<--CWaitE32ImageSize::ConstructL"));
    }

CWaitE32ImageSize::~CWaitE32ImageSize()
    {
    LOG(_L("-->CWaitE32ImageSize::~CWaitE32ImageSize"));
    Cancel();
    LOG(_L("<--CWaitE32ImageSize::~CWaitE32ImageSize"));
    }

void CWaitE32ImageSize::RunL()
    {
    TInt error = iStatus.Int();
    LOG2(_L("-->CWaitE32ImageSize::RunL(%d)"), error);
    if (KErrCancel != error)
        {
        User::LeaveIfError(error);
        switch (iState)
            {
            case EWaitForSignalOne:
                {
                iState = KExpectedHostSignalOne == iBuffer() ? EWaitForSignalTwo : EWaitForSignalOne;
                break;
                }
            case EWaitForSignalTwo:
                {
                iState = KExpectedHostSignalTwo == iBuffer() ? EWaitForSignalThree : EWaitForSignalOne;
                break;
                }
            case EWaitForSignalThree:
                {
                iState = KExpectedHostSignalThree == iBuffer() ? EReadImageSize : EWaitForSignalOne;
                break;
                }
            case EReadImageSize:
                {
                iModel.CreateSandboxL(iBuffer());
                User::Leave(KErrNone);
                break;
                }
            default:
                {
                User::Leave(KErrArgument);
                break;
                }
            }
        iBuffer.Zero();
        RequestHostData(iBuffer);
        }
    LOG(_L("<--CWaitE32ImageSize::RunL"));
    }

void CWaitE32ImageSize::DoCancel()
    {
    LOG(_L("-->CWaitE32ImageSize::DoCancel"));
    iModel.HostLink().CancelReadHost();
    LOG(_L("<--CWaitE32ImageSize::DoCancel"));
    }

TInt CWaitE32ImageSize::RunError(TInt aError)
    {
    LOG2(_L("-->CWaitE32ImageSize::RunError(%d)"), aError);
    iModel.WaitE32ImageSizeComplete(aError);
    LOG(_L("<--CWaitE32ImageSize::RunError"));
    return KErrNone;
    }

void CWaitE32ImageSize::RequestHostData(TDes8& aDes)
    {
    LOG(_L("-->CWaitE32ImageSize::RequestHostData"));
    iStatus = KRequestPending;
    iModel.HostLink().ReadHost(aDes, iStatus);
    SetActive();
    LOG(_L("<--CWaitE32ImageSize::RequestHostData"));
    }
